{/* Copyright 2020 Adobe. All rights reserved.
This file is licensed to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy
of the License at http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under
the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
OF ANY KIND, either express or implied. See the License for the specific language
governing permissions and limitations under the License. */}

import colorTypes from 'docs:@react-types/color/src/index.d.ts';
import docs from 'docs:@react-spectrum/color';
import {HeaderInfo, PropTable, TypeLink, PageDescription} from '@react-spectrum/docs';
import {Layout} from '@react-spectrum/docs';
import packageData from '@react-spectrum/color/package.json';
import statelyDocs from 'docs:@react-stately/color';

export default Layout;

```jsx import
import {ColorSlider} from '@react-spectrum/color';
import {Flex} from '@react-spectrum/layout';
```

---
category: Color
keywords: [color slider]
---

# ColorSlider

<PageDescription>{docs.exports.ColorSlider.description}</PageDescription>

<HeaderInfo
  packageData={packageData}
  componentNames={['ColorSlider']}
  sourceData={[
    {type: 'Spectrum', url: 'https://spectrum.adobe.com/page/color-slider/'}
  ]}
  since="3.35.0" />

## Example

```tsx example
<ColorSlider defaultValue="#7f0000" channel="red" />
```

## Value

A ColorSlider requires either an uncontrolled default value or a controlled value, provided using the `defaultValue` or `value` props respectively.
The value provided to either of these props should be a color string or <TypeLink links={colorTypes.links} type={colorTypes.exports.Color} /> object. The `channel` prop must also be provided to specify which color channel the slider should display. This must be one of the channels included in the color value, for example, for RGB colors, the "red", "green", and "blue" channels are available. For a full list of supported channels, see the [Props](#props) table below.

In the example below, the <TypeLink links={statelyDocs.links} type={statelyDocs.exports.parseColor} /> function is used to parse the initial color from a HSL string
so that `value`'s type remains consistent.

```tsx example
import {parseColor} from '@react-stately/color';

function Example() {
  let [value, setValue] = React.useState(parseColor('hsl(0, 100%, 50%)'));
  return (
    <Flex gap="size-300" wrap>
      <ColorSlider
        label="Hue (uncontrolled)"
        defaultValue="hsl(0, 100%, 50%)"
        channel="hue" />
      <ColorSlider
        label="Hue (controlled)"
        value={value}
        onChange={setValue}
        channel="hue" />
    </Flex>
  );
}
```

### HTML forms

ColorSlider supports the `name` prop for integration with HTML forms. The value will be submitted as a number between the minimum and maximum value for the displayed channel.

```tsx example
<ColorSlider
  defaultValue="#7f0000"
  channel="red"
  name="red" />
```

## Labeling

The ColorSlider's channel name and value are shown above the ColorSlider by default. The label and value label can be hidden by providing
`label={null}` and `showValueLabel={false}` to the ColorSlider, respectively. In addition, a custom label can be provided via the `label` prop.

```tsx example
<Flex gap="size-300" wrap alignItems="end">
  <ColorSlider channel="saturation" defaultValue="hsl(0, 100%, 50%)" label={null} />
  <ColorSlider channel="lightness" defaultValue="hsl(0, 100%, 50%)" showValueLabel={false} />
</Flex>
```

### Accessibility

If the ColorSlider's label is hidden, a localized string for the channel name is used as the `aria-label` by default. The value of the ColorSlider
is also automatically localized and provided to the input as `aria-valuetext` regardless of the value label's visibility. If you provide your own `aria-label`
or `aria-labelledby`, be sure to localize the string or labeling element appropriately.

### Internationalization

For languages that are read right-to-left (e.g. Hebrew and Arabic), the layout of the ColorSlider is automatically flipped. As mentioned previously,
ColorSlider automatically uses the current locale to format the channel and value label.

## Events

ColorSlider supports two events: `onChange` and `onChangeEnd`. `onChange` is triggered whenever the ColorSlider's handle is dragged, and `onChangeEnd`
is triggered when the user stops dragging the handle. Both events receive a <TypeLink links={colorTypes.links} type={colorTypes.exports.Color} /> object
as a parameter.

The example below uses `onChange` and `onChangeEnd` to update two separate elements with the ColorSlider's value.

```tsx example
function Example() {
  let [currentValue, setCurrentValue] = React.useState(parseColor('hsl(50, 100%, 50%)'));
  let [finalValue, setFinalValue] = React.useState(parseColor('hsl(50, 100%, 50%)'));

  return (
    <div>
      <ColorSlider
        value={currentValue}
        channel="hue"
        onChange={setCurrentValue}
        onChangeEnd={setFinalValue} />
      <pre>Current value: {currentValue.toString('hsl')}</pre>
      <pre>Final value: {finalValue.toString('hsl')}</pre>
    </div>
  );
}
```

## Creating a color picker

### RGBA

This example shows how you could build an RGBA color picker using four color sliders bound to the same
color value in state. The <TypeLink links={statelyDocs.links} type={statelyDocs.exports.parseColor} />
function is used to parse the initial color from a hex value, stored in state. The `value` and `onChange` props
of ColorSlider are used to make the sliders controlled, so that they all update when the color is modified.

```tsx example
function Example() {
  let [color, setColor] = React.useState(parseColor('#ff00ff'));

  return (
    <Flex direction="column">
      <ColorSlider channel="red" value={color} onChange={setColor} />
      <ColorSlider channel="green" value={color} onChange={setColor} />
      <ColorSlider channel="blue" value={color} onChange={setColor} />
      <ColorSlider channel="alpha" value={color} onChange={setColor} />
    </Flex>
  );
}
```

### HSLA

This example shows how to build a similar color picker to the one above, using HSLA colors instead.

```tsx example
function Example() {
  let [color, setColor] = React.useState(parseColor('hsla(0, 100%, 50%, 0.5)'));

  return (
    <Flex direction="column">
      <ColorSlider channel="hue" value={color} onChange={setColor} />
      <ColorSlider channel="saturation" value={color} onChange={setColor} />
      <ColorSlider channel="lightness" value={color} onChange={setColor} />
      <ColorSlider channel="alpha" value={color} onChange={setColor} />
    </Flex>
  );
}
```

### HSBA

This example shows how to build an HSBA color picker.

```tsx example
function Example() {
  let [color, setColor] = React.useState(parseColor('hsba(0, 100%, 50%, 0.5)'));
  return (
    <>
      <ColorSlider channel="hue" value={color} onChange={setColor} />
      <ColorSlider channel="saturation" value={color} onChange={setColor} />
      <ColorSlider channel="brightness" value={color} onChange={setColor} />
      <ColorSlider channel="alpha" value={color} onChange={setColor} />
    </>
  );
}
```

## Props

<PropTable component={docs.exports.ColorSlider} links={docs.links} />

## Visual options

### Disabled
[View guidelines](https://spectrum.adobe.com/page/color-slider/#Disabled)

```tsx example
<ColorSlider defaultValue="#7f0000"  channel="red" isDisabled />
```

### Vertical
[View guidelines](https://spectrum.adobe.com/page/color-slider/#Orientation)

```tsx example
<ColorSlider defaultValue="#7f0000" channel="red" orientation="vertical" />
```

### Custom Size
[View guidelines](https://spectrum.adobe.com/page/color-slider/#Length)

```tsx example
<Flex direction="column" gap="size-300">
  <ColorSlider defaultValue="#7f0000" channel="red" orientation="vertical" height="size-3600" />
  <ColorSlider defaultValue="#7f0000" channel="red" width="size-3600" maxWidth="100%" />
</Flex>
```

### Contextual help

A [ContextualHelp](ContextualHelp.html) element may be placed next to the label to provide additional information or help about a ColorSlider.

```tsx example
import {Content, ContextualHelp, Heading} from '@adobe/react-spectrum';

<ColorSlider
  label="Accent Color"
  channel="hue"
  defaultValue="hsl(120, 100%, 50%)"
  contextualHelp={
    <ContextualHelp>
      <Heading>What is an accent color?</Heading>
      <Content>An accent color is the primary foreground color for your theme, used across all components.</Content>
    </ContextualHelp>
  } />
```

## Testing

The ColorSlider features a draggable handle that the user can interact with to change its color value.
Please see the following section in the testing docs for more information on how to simulate this action in your
test suite.

[Simulating move event](./testing.html#simulating-move-event)

Please also refer to [React Spectrum's test suite](https://github.com/adobe/react-spectrum/blob/main/packages/%40react-spectrum/color/test/ColorArea.test.tsx) if you find that the above
isn't sufficient when resolving issues in your own test cases.
